package frogermcs.io.likeanimation.widget;

import frogermcs.io.likeanimation.ArgbEvaluator;
import frogermcs.io.likeanimation.Property;
import frogermcs.io.likeanimation.util.PixelMapUtils;
import frogermcs.io.likeanimation.util.Utils;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.render.*;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.media.image.PixelMap;
import ohos.media.image.common.PixelFormat;

public class CircleView extends Component
        implements Component.BindStateChangedListener,
        Component.DrawTask {

    private static final int START_COLOR = 0xFFFF5722;
    private static final int END_COLOR = 0xFFFFC107;

    private ArgbEvaluator argbEvaluator = new ArgbEvaluator();

    private Paint circlePaint = new Paint();
    private Paint maskPaint = new Paint();

    private PixelMap tempBitmap;
    private Canvas tempCanvas;

    private float outerCircleRadiusProgress = 0f;
    private float innerCircleRadiusProgress = 0f;

    private int maxCircleSize;

    public CircleView(Context context) {
        this(context, null);
    }

    public CircleView(Context context, AttrSet attrSet) {
        this(context, attrSet, null);
    }

    public CircleView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);

        init();
    }

    private void init() {
        setBindStateChangedListener(this);
        addDrawTask(this);
        circlePaint.setStyle(Paint.Style.FILL_STYLE);
        circlePaint.setAntiAlias(true);
        maskPaint.setBlendMode(BlendMode.CLEAR);
        maskPaint.setAntiAlias(true);
    }

    @Override
    public void onComponentBoundToWindow(Component component) {
        int w = getWidth();
        maxCircleSize = w / 2;
        tempBitmap = PixelMapUtils.createBitmap(getWidth(),
                getWidth(),
                PixelFormat.ARGB_8888);
        tempCanvas = new Canvas(new Texture(tempBitmap));
    }

    @Override
    public void onComponentUnboundFromWindow(Component component) {

    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        tempCanvas.drawColor(0xFFFFFF, BlendMode.CLEAR);
        tempCanvas.drawCircle(getWidth() / 2,
                getHeight() / 2,
                outerCircleRadiusProgress * maxCircleSize,
                circlePaint);
        tempCanvas.drawCircle(getWidth() / 2,
                getHeight() / 2,
                innerCircleRadiusProgress * maxCircleSize,
                maskPaint);
        PixelMapHolder holder = new PixelMapHolder(tempBitmap);
        canvas.drawPixelMapHolder(holder, 0, 0, new Paint());
    }

    public void setInnerCircleRadiusProgress(float innerCircleRadiusProgress) {
        this.innerCircleRadiusProgress = innerCircleRadiusProgress;
        invalidate();
    }

    public float getInnerCircleRadiusProgress() {
        return innerCircleRadiusProgress;
    }

    public void setOuterCircleRadiusProgress(float outerCircleRadiusProgress) {
        this.outerCircleRadiusProgress = outerCircleRadiusProgress;
        updateCircleColor();
        invalidate();
    }

    private void updateCircleColor() {

        float colorProgress = (float) Utils.clamp(outerCircleRadiusProgress, 0.5, 1);
        colorProgress = (float) Utils.mapValueFromRangeToRange(colorProgress,
                0.5f,
                1f,
                0f,
                1f);
        this.circlePaint.setColor(new Color((Integer) argbEvaluator
                .evaluate(colorProgress, START_COLOR, END_COLOR)));

        if (colorProgress == 1) {
            this.circlePaint.setColor(Color.TRANSPARENT);
        }
    }

    public float getOuterCircleRadiusProgress() {
        return outerCircleRadiusProgress;
    }

    public static final Property<CircleView, Float> INNER_CIRCLE_RADIUS_PROGRESS =
            new Property<CircleView, Float>(Float.class, "innerCircleRadiusProgress") {
                @Override
                public Float get(CircleView object) {
                    return object.getInnerCircleRadiusProgress();
                }

                @Override
                public void set(CircleView object, Float value) {
                    object.setInnerCircleRadiusProgress(value);
                }
            };

    public static final Property<CircleView, Float> OUTER_CIRCLE_RADIUS_PROGRESS =
            new Property<CircleView, Float>(Float.class, "outerCircleRadiusProgress") {
                @Override
                public Float get(CircleView object) {
                    return object.getOuterCircleRadiusProgress();
                }

                @Override
                public void set(CircleView object, Float value) {
                    object.setOuterCircleRadiusProgress(value);
                }
            };
}
